// src目录放源代码，不会拿来运行的
// 运行的是dist目录

// 指定任务

const gulp = require('gulp'),
      htmlmin = require('gulp-htmlmin'),
      cleanCss = require('gulp-clean-css'),
      autoprefixer = require('gulp-autoprefixer'),
      uglify = require('gulp-uglify'),
      babel = require('gulp-babel'),
      del = require('del'),
      connect = require('gulp-connect'),
      sass = require('gulp-sass'),
      proxy = require('http-proxy-middleware')

// gulp指定任务使用task方法
// gulp.task()

// 可以提前把所有要处理的文件路径做一个统一规划
// 这个不是必须的，也可以在各个任务里分散定义路径，但是集中管理这种思想要有
const paths = {
  html: {
    src: 'src/**/*.html',
    dest: 'dist'
  },
  css: {
    src: 'src/css/**/*.scss',
    dest: 'dist/css'
  },
  js: {
    src: 'src/js/**/*.js',
    dest: 'dist/js'
  },
  img: {
    src: 'src/images/**/*',
    dest: 'dist/images'
  },
  libs: {
    src: 'src/libs/**/*',
    dest: 'dist/libs'
  }
}

// 指定一个删除dist目录的任务
const delDist = () => {
  return del(['dist'])
}

// 指定一个html任务：把src里的html文件取出来，压缩，放到dist目录里
const html = () => {
  // ** 代表所有目录
  // * 代表所有文件
  // 下面这句话的意思是取出src目录下的所有目录的所有html文件
  return gulp.src(paths.html.src)
    .pipe(htmlmin({
      removeComments: true,//清除HTML注释
      collapseWhitespace: true,//压缩HTML
      collapseBooleanAttributes: true,//省略布尔属性的值 <input checked="true"/> ==> <input checked />
      removeEmptyAttributes: true,//删除所有空格作属性值 <input id="" /> ==> <input />
      removeScriptTypeAttributes: false,//删除<script>的type="text/javascript"
      removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css"
      minifyJS: true,//压缩页面JS
      minifyCSS: true//压缩页面CSS
    }))
    .pipe(gulp.dest(paths.html.dest))
    .pipe(connect.reload())
}

// 指定css任务：先把所有css文件取出来，先编译，加上兼容前缀，再压缩，最后放到dist目录里
const css = () => {
  return gulp.src(paths.css.src)
    .pipe(sass())
    .pipe(autoprefixer({
      overrideBrowserslist: ['last 2 versions']
    }))
    // .pipe(cleanCss())
    .pipe(gulp.dest(paths.css.dest))
    .pipe(connect.reload())
}

// 指定js任务：把js文件取出来，先ES6转ES5，再压缩，最后放到dist里
// babel会使用ES5的语法实现跟ES6等价的程序
const js = () => {
  return gulp.src(paths.js.src)
    .pipe(babel({
      presets: ['@babel/env']
    }))
    .pipe(uglify())
    .pipe(gulp.dest(paths.js.dest))
    .pipe(connect.reload())
}

// 指定img任务：从src目录里拿到所有图片，移动到dist即可
const img = () => {
  return gulp.src(paths.img.src)
    .pipe(gulp.dest(paths.img.dest))
}

// 指定libs任务：从src目录里拿到所有libs文件，移动到dist即可
const libs = () => {
  return gulp.src(paths.libs.src)
    .pipe(gulp.dest(paths.libs.dest))
}

// 开启服务器任务，端口号2333，根目录是dist，支持热更新
// $.get('http://localhost:8080/api/login.php')
// $.get('/api/login.php')
const server = () => {
  connect.server({
    port: 2333,
    root: 'dist',
    livereload: true,
    //中间件，指的是在请求响应过程当中做一些处理
    //是一个函数，放回置是一个数组，在数组里配置代理跨域
    middleware(){
      return[
        //将前端请求以/api开头的代理到8080端口
        proxy('/api',{
          target:'http://localhost:8080',
          changeOrigin:true
        })
      ]
    }
  })
}

// 指定监听任务：监听文件修改，自动重启对应任务
const watch = () => {
  gulp.watch(paths.html.src, html)
  gulp.watch(paths.css.src, css)
  gulp.watch(paths.js.src, js)
}

// 把指定的任务导出
// module.exports = {
//   html,
//   css,
//   js,
//   img,
//   libs
// }

// 我们只需要导出一个默认任务，这个默认任务里就包含了我们想要执行的所有任务
// series是同步，意味着第一个任务执行结束了才能执行第二个
// parallel是异步，意味着这些任务是同时开始运行的
module.exports.default = gulp.series(delDist, gulp.parallel(server, html, js, css, img, libs, watch))
